const tool = require('../FunctionTool.js')
const spo2Analyzer = require('./CRSpo2Analyze.js')

const pc100 = "PC-100"
const pc200 = "PC-200"
const pc300 = "PC_300"
const pc80b = "PC80B"
const h600 = "H600"
const pod = "POD"
const ap_10 = "AP-10"
const ap_20 = "AP-20"
const sp_20 = "SP-20"
const pc_60nw = "PC-60NW"
const pc_60nw_1 = "PC-60NW-1"

const pc_68b = "PC-68B"
const pc_66b = "PC-66B"
const pc_60f = "PC-60F"

const oxySmart = "OxySmart "  //定制版PC-60F
const babyOximeter = "BabyOximeter"


const eBody_Scale = "eBody-Scale"

const supportDevices = [pc100, pc200, pc300, pod, ap_10, ap_20, sp_20, pc_60nw, pc_60nw_1, pc_68b, pc_66b, pc_60f, oxySmart, babyOximeter]

function setDelegate(delegate) {
    /** 设置代理的方法 */
    this.delegate = new Object()
    //获取蓝牙适配器状态
    this.delegate.CRBleManagerBleStateChanged = delegate['GetBluetoothAdapterState']
    //搜索完成
    this.delegate.CRBleManagerOnSearchComplete = delegate['SearchComplete']
    //成功连接设备
    this.delegate.CRBleManagerOnDidConnectDevice = delegate['DidConnectDevice']
    //断开连接
    this.delegate.CRBleManagerOnDidDisconnectDevice = delegate['DidDisconnectDevice']
    //初始化成功
    this.delegate.CRBleManagerBluetoothInitSuccessed = delegate['BluetoothInitSuccessed']
    //初始化失败
    this.delegate.CRBleManagerBluetoothInitFailed = delegate['BluetoothInitFailed']

    //连接失败
    this.delegate.CRBleManagerOnConnectFailed = delegate['ConnectFailed']
    this.adapterState = false
    this.discovering = false

    var that = this
    //打开蓝牙适配器
    wx.openBluetoothAdapter({
        success: function (res) {
            //获取蓝牙适配器状态
            wx.getBluetoothAdapterState(
                {
                    success: (e) => {
                        console.log(e, '获取蓝牙适配器状态成功')
                        that.adapterState = e.available
                        that.discovering = e.discovering
                        if (that.delegate.CRBleManagerBluetoothInitSuccessed)
                            that.delegate.CRBleManagerBluetoothInitSuccessed(e)

                    },
                    fail: (e) => {
                        console.log(e, '获取蓝牙适配器状态失败')
                        if (that.delegate.CRBleManagerBluetoothInitFailed)
                            that.delegate.CRBleManagerBluetoothInitFailed(res)
                        console.log(e)
                    },
                })
        },
        fail: function (res) {
            that.adapterState = res.available
            that.discovering = res.discovering
            if (that.delegate.CRBleManagerBluetoothInitFailed)
                that.delegate.CRBleManagerBluetoothInitFailed(res)
            console.log(res)

        },
    })

    //监听蓝牙适配器状态
    wx.onBluetoothAdapterStateChange(function (res) {
        console.log(res, '监听蓝牙适配器状态')
        //可用状态没发生变化，搜索状态发生变化，不处理
        if (res.available == that.adapterState)
            return
        //蓝牙可用状态发生变化
        that.adapterState = res.available
        that.discovering = res.discovering
        if (that.delegate.CRBleManagerBleStateChanged)
            that.delegate.CRBleManagerBleStateChanged(res)
    })
    /** 设置this的方法 */
    //初始化设备
    this.CRBleDevice = () => {
        var device = new Object()
        device.name = ""
        device.deviceID = ""
        device.servicedID = ""
        device.writeCharacteristicValue = ""
        device.connected = false
        device.writeValue = function (arr) {
            // 向蓝牙设备发送一个0x00的16进制数据
            let buffer = new Uint8Array(arr)
            wx.writeBLECharacteristicValue({
                deviceId: this.deviceID,
                serviceId: this.servicedID,
                characteristicId: this.writeCharacteristicValue,
                value: buffer.buffer,
            })
        }
        return device
    },
        //变量
        this.data =
            {
                //保存发现的设备
                devices: [],
                //保存已连接的设备
                connectedDevices: [],
                connected: false,
                //保存已连接设备的心跳包超时定时器
                heartPackageTimers: [],
                //保存已连接设备的心跳包标识(标记2s内是否有过通信)
                heartPackageFlags: [],
            },
        //根据设备ID获取已发现的设备
        this.getFoundDeviceWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.devices.length; i++) {
                if (this.data.devices[i]['deviceID'] === deviceID)
                    return this.data.devices[i]['device']
            }
            return null
        },
        //根据设备ID删除已发现的设备
        this.deleteFoundDeviceWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.devices.length; i++) {
                if (this.data.devices[i]['deviceID'] === deviceID)
                    this.data.devices.splice(i, 1)
            }
            // return null
        },

        //根据设备ID获取心跳包超时定时器
        this.getHeartPackageTimerWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.heartPackageTimers.length; i++) {
                if (this.data.heartPackageTimers[i]['deviceID'] === deviceID)
                    return this.data.heartPackageTimers[i]['heartPackageTimer']
            }
            return null
        },
        //根据设备ID添加心跳包定时器
        this.setHeartPackageTimerWithDeviceID = (deviceID) => {
            let that = this
            var timers = this.data.heartPackageTimers
            let device = that.getConnectedDeviceWithDeviceID(deviceID)
            var interver = isSpo2Device(device.name) ? 1000 : 4500
            var heartPackageTimer = setInterval(function () {
                that.checkConnecton(deviceID)
            }, interver)
            timers[timers.length] =
                {
                    'deviceID': deviceID, 'heartPackageTimer': heartPackageTimer
                }
            // return null
        },

        //根据设备ID删除心跳包定时器
        this.deleteHeartPackageTimerWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.heartPackageTimers.length; i++) {
                if (this.data.heartPackageTimers[i]['deviceID'] === deviceID) {
                    clearInterval(this.data.heartPackageTimers[i]['heartPackageTimer'])
                    this.data.heartPackageTimers.splice(i, 1)
                }
            }
            // return null
        },
        //根据设备ID获取心跳包通信标识
        this.getHeartPackageFlagWithDeviceID = (deviceID) => {
            var flags = this.data.heartPackageFlags
            for (let i = 0; i < flags.length; i++) {
                if (flags[i]['deviceID'] === deviceID)
                    return flags[i]['heartPackageFlag']
            }
            return null
        },
        //根据设备ID设置心跳包通信标识
        this.setHeartPackageFlagWithDeviceID = (deviceID, flag) => {
            var flags = this.data.heartPackageFlags
            //设置已存在的标识
            for (let i = 0; i < flags.length; i++) {
                if (flags[i]['deviceID'] === deviceID) {
                    flags[i]['heartPackageFlag'] = flag
                    return
                }
            }
            //不存在时，添加一个
            flags[flags.length] =
                {
                    'deviceID': deviceID, 'heartPackageFlag': flag
                }
        },
        //根据设备ID删除心跳包通信标识
        this.deleteHeartPackageFlagWithDeviceID = (deviceID) => {
            console.log('deviceID',JSON.stringify(deviceID));
            console.log('this.data.devices', JSON.stringify(this.data.devices));
            console.log('this.data.heartPackageFlags',JSON.stringify(this.data.heartPackageFlags));
            for (let i = 0; i < this.data.devices.length; i++) {
                if (this.data.heartPackageFlags[i]['deviceID'] === deviceID)
                    this.data.heartPackageFlags.splice(i, 1)
                    break; 
            }
            // return null
        },

        //根据设备ID获取已连接的设备
        this.getConnectedDeviceWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.connectedDevices.length; i++) {
                if (this.data.connectedDevices[i]['deviceID'] === deviceID)
                    return this.data.connectedDevices[i]['device']
            }
            return null
        },
        //根据设备ID删除已连接的设备
        this.deleteConnectedDeviceWithDeviceID = (deviceID) => {
            for (let i = 0; i < this.data.connectedDevices.length; i++) {
                if (this.data.connectedDevices[i]['deviceID'] === deviceID)
                    this.data.connectedDevices.splice(i, 1)
            }
            // return null
        },
        this.checkConnecton = (deviceID) => {
            let device = this.getConnectedDeviceWithDeviceID(deviceID)
            var flag = this.getHeartPackageFlagWithDeviceID(deviceID)
            if (flag) {
                this.setHeartPackageFlagWithDeviceID(deviceID, false)
                return
            }
            //表示没有通信，需要断开连接
            //断开
            closeConnection(device)
        }

    //开始搜索
    this.startBluetoothDevicesDiscovery = () => {
        //微信API没有记录蓝牙的搜索状态，就用了一个给全局变量 this加了个属性来标记搜索状态。
        if (this._discoveryStarted)
            return
        //置空上一次发现的设备
        this.data.devices = []
        //标记为正在搜索
        this._discoveryStarted = true
        console.log("开始搜索--->")
        //保存this
        var that = this
        wx.startBluetoothDevicesDiscovery(
            {
                allowDuplicatesKey: true,
                success: (res) => {
                    // console.log('startBluetoothDevicesDiscovery success', res)
                    this.onBluetoothDeviceFound()
                },
            })
        setTimeout(function () {
            that.handleDiscoveryDevices()
        }, 4000);
    },
        //停止搜索
        this.stopBluetoothDevicesDiscovery = () => {
            //标记为正在搜索
            this._discoveryStarted = false
            wx.stopBluetoothDevicesDiscovery()
            console.log("停止搜索")
        },
        //发现设备
        this.onBluetoothDeviceFound = () => {
            wx.onBluetoothDeviceFound((res) => {
                res.devices.forEach(device => {
                    // var	string deviceName = device.localName
                    if ((device.name == null) && (device.localName == null))
                        return
                    const foundDevices = this.data.devices
                    // const idx = inArray(foundDevices, 'deviceId', device.deviceId)
                    // const data = {}
                    var deviceModel = this.CRBleDevice()
                    deviceModel.deviceID = device.deviceId

                    deviceModel.name = device.localName ? device.localName : device.name
                    // console.log(deviceModel.name)
                    if (tool.inArray(foundDevices, "deviceID", device.deviceId) !== -1)
                        return
                    foundDevices[foundDevices.length] =
                        {
                            'device': deviceModel, 'deviceID': deviceModel.deviceID
                        }
                    // if (idx === -1)
                    // 	data[`devices[${foundDevices.length}]`] = device
                    // else
                    // 	data[`devices[${idx}]`] = device
                    // this.setData(data)
                })
            })
        },
        //发现设备服务
        this.getBLEDeviceServices = (deviceId) => {
            var that = this
            wx.getBLEDeviceServices({
                deviceId,
                success: (res) => {
                    that.foundServiceID(deviceId, res)
                }
            })

        },
        this.foundServiceID = (deviceId, res) => {
					console.log(this.data.devices,'GGGGGGGGGGGG')
            const device = this.getFoundDeviceWithDeviceID(deviceId)
            console.log(device);
            if ((device.name.indexOf(pc_60nw) != -1) && (device.name.indexOf(pc_60nw_1) == -1)) {
                for (let i = 0; i < res.services.length; i++) {
                    if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFF0") != -1) {
                        //保存服务ID
                        device.servicedID = res.services[i].uuid
                        this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                        return
                    }
                }
            }
            //血氧
            if ((device.name.indexOf(ap_10) != -1) || (device.name.indexOf(ap_20) != -1) || (device.name.indexOf(pod) != -1) || (device.name.indexOf(pc_68b) != -1) || (device.name.indexOf(pc_60nw_1) != -1)) {
                for (var i = 0; i < res.services.length; i++) {
                    if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFB0") != -1) {
                        //保存服务ID
                        device.servicedID = res.services[i].uuid
                        this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                        return
                    }
                }
                return
            }
            if ((device.name.indexOf(pc_60f) != -1) || (device.name.indexOf(oxySmart) != -1) || (device.name.indexOf(babyOximeter) != -1)) {
                for (var i = 0; i < res.services.length; i++) {
                    if (res.services[i].isPrimary && res.services[i].uuid.indexOf("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") != -1) {
                        //保存服务ID
                        device.servicedID = res.services[i].uuid
                        this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                        return
                    }
                }
                return
            }
            // if ( (device.name.indexOf("PC-60NW") != -1))
            // {
            // 	for (let i = 0; i < res.services.length; i++) {
            // 		if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFF0") != -1) {
            // 			//保存服务ID
            // 			device.servicedID = res.services[i].uuid
            // 			this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            // 			return
            // 		}
            // 	}
            // 	return
            // }
            if ((device.name.indexOf(pc100) != -1) || (device.name.indexOf(pc200) != -1) || (device.name.indexOf(pc300) != -1) || (device.name.indexOf(pc_66b) != -1) || (device.name.indexOf(sp_20) != -1)) {
                for (var i = 0; i < res.services.length; i++) {
                    if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFF0") != -1) {
                        //保存服务ID
                        device.servicedID = res.services[i].uuid
                        this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                        return
                    }
                }
                return
            }
        }

    this.handleDiscoveryDevices = () => {
        //停止搜索
        this.stopBluetoothDevicesDiscovery()
        //返回搜索到的数组
        const foundDevices = this.data.devices
        // [foundDevices.map(function (deviceItem) {
        // 	return deviceItem['device'];
        // })]
        if (this.delegate.CRBleManagerOnSearchComplete)
            this.delegate.CRBleManagerOnSearchComplete(foundDevices.map(function (deviceItem) {
                    return deviceItem['device']
                })
            )
    },
        //发现设备服务特征值
        this.getBLEDeviceCharacteristics = (deviceId, serviceId) => {
            let that = this
            wx.getBLEDeviceCharacteristics({
                deviceId,
                serviceId,
                success: (res) => {
                    that.handleCharacteristicsID(deviceId, res)
                },
                fail(res) {
                    console.error('getBLEDeviceCharacteristics', res)
                }
            })

            // 操作之前先监听，保证第一时间获取数据
            wx.onBLECharacteristicValueChange(function (characteristic) {
                //获取设备
                const device = that.getConnectedDeviceWithDeviceID(deviceId)
                //buffer转为数字数组
                var valueArray = tool.arrayBufferToNumberArray(characteristic.value)
                console.log(valueArray, '获取到的特征值')
                //分析数组
                if (isSpo2Device(device?.name)) {
                    that.setHeartPackageFlagWithDeviceID(deviceId, true)
                    spo2Analyzer.appendingNewData(valueArray, device)
                }
                // if ((device.name.indexOf(pc100) != -1) || (device.name.indexOf(pc200) != -1) || (device.name.indexOf(pc300) != -1))
                // {
                // 	that.setHeartPackageFlagWithDeviceID(deviceId, true)
                // 	pc300Analyzer.appendingNewData(valueArray, device)
                // }
            })

            wx.onBLEConnectionStateChange(function (res) {
                if (res.connected == false) {
                    // device为空，已经处理过一次断开连接。系统回调较慢。不处理
                    let device = that.getConnectedDeviceWithDeviceID(res.deviceId)
                    if (device == null) return
                    //执行断开回调
                    that.executeDisconnectIonCallBack(device)
                }
            })
        }
    this.executeDisconnectIonCallBack = (device) => {
        if (this.delegate.CRBleManagerOnDidDisconnectDevice)
            this.delegate.CRBleManagerOnDidDisconnectDevice(device)
        this.cleanConnectionStorage(device.deviceID)
    }
    //清理连接后缓存的信息
    this.cleanConnectionStorage = (deviceID) => {
        this.deleteConnectedDeviceWithDeviceID(deviceID)
        this.deleteHeartPackageFlagWithDeviceID(deviceID)
        this.deleteHeartPackageTimerWithDeviceID(deviceID)
    }

    this.foundCharacteristicsID = (deviceId) => {
        let device = this.getFoundDeviceWithDeviceID(deviceId)
        if ((device.name.indexOf(pod) != -1) || (device.name.indexOf(pc_68b) != -1) || (device.name.indexOf(pc_60nw) != -1) || (device.name.indexOf(ap_10) != -1) || (device.name.indexOf(ap_20) != -1)) {
            //pc_60nw 和 pc_60nw_1 都能进这里，在此区分，不包含pc_60nw_1的为FFF1,2
            if ((device.name.indexOf(pc_60nw_1) == -1) && (device.name.indexOf(pc_60nw) != -1)) {
                return { read: "FFF1", write: "FFF2" }
            }
            return { read: "FFB2", write: "FFB2" }
        }

        if ((device.name.indexOf(pc_60f) != -1) || (device.name.indexOf(oxySmart) != -1) || (device.name.indexOf(babyOximeter) != -1))
            return { read: "6E400003-B5A3-F393-E0A9-E50E24DCCA9E", write: "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" }
        // if (device.name == "PC-60NW")
        // 	return { read: "FFF1", write: "FFF2" }
        if ((device.name.indexOf(pc100) != -1) || (device.name.indexOf(pc200) != -1) || (device.name.indexOf(pc300) != -1) || (device.name.indexOf(pc_66b) != -1) || (device.name.indexOf(sp_20) != -1))
            return { read: "FFF1", write: "FFF2" }
    }

    this.handleCharacteristicsID = (deviceId, res) => {
        let device = this.getFoundDeviceWithDeviceID(deviceId)
        let serviceId = device.servicedID
        let characs = this.foundCharacteristicsID(deviceId)
        for (let i = 0; i < res.characteristics.length; i++) {
            let item = res.characteristics[i]
            //1.保存写特征值
            if (item.properties.write && item.uuid.indexOf(characs.write) != -1)
                device.writeCharacteristicValue = item.uuid
            //2.订阅
            if (item.properties.notify && item.uuid.indexOf(characs.read) != -1) {
                let that = this
                wx.notifyBLECharacteristicValueChange({
                    deviceId,
                    serviceId,
                    characteristicId: item.uuid,
                    state: true,
                    success: function () {
                        //已连接数组加入
                        that.data.connectedDevices[that.data.connectedDevices.length] =
                            { deviceID: deviceId, device: that.getFoundDeviceWithDeviceID(deviceId) }
                        //已发现数组删除
                        // that.deleteFoundDeviceWithDeviceID(deviceId)
                        that.data.devices == []
                        if (that.timeOut) {
                            clearTimeout(that.timeOut)
                            that.timeOut = null
                        }
                        //告诉完成连接
                        if (that.delegate.CRBleManagerOnDidConnectDevice)
                            that.delegate.CRBleManagerOnDidConnectDevice(that.getConnectedDeviceWithDeviceID(deviceId))
                        //设置通信标识
                        that.setHeartPackageFlagWithDeviceID(deviceId, true)
                        setTimeout(function () {
                            //设置心跳包超时
                            that.setHeartPackageTimerWithDeviceID(deviceId)
                        }, 200)
                    }
                })
            }
        }
    }


}


function startSearch() {
    let that = this
    this.data.devices = []
    //判断当前蓝牙适配器是否已打开
    if (this.adapterState) {
        //是否正在搜索
        if (this.discovering === false)
            that.startBluetoothDevicesDiscovery()
    }
    //未打开
    // wx.openBluetoothAdapter({
    // 	success: (res) => {
    // 		that.startBluetoothDevicesDiscovery()
    // 	},
    // 	fail: (res) =>
    // 	{
    // 		if (that.delegate.CRBleManagerBleStateChanged)
    // 			that.delegate.CRBleManagerBleStateChanged(res)
    // 		// if (res.errCode === 10001)
    // 		// 	wx.onBluetoothAdapterStateChange(function (res)
    // 		// 	 {
    // 		// 		if (res.available)
    // 		// 			that.startBluetoothDevicesDiscovery()
    // 		// 	})
    // 	}
    // })

}

function stopSearch() {
    let that = this
    this.data.devices = []
    //判断当前蓝牙适配器是否已打开
    if (this.adapterState) {
        //是否正在搜索
        if (this.discovering == true)
            that.stop()
        return
    }
}


function connectDevice(device) {
    // const ds = e.currentTarget.dataset
    if (device == null)
        return
    const deviceId = device.deviceID
    //超时定时器
    var that = this
    if (this.timeOut == null) {
        this.timeOut = setTimeout(function () {
            closeConnection(device)
            if (that.delegate.CRBleManagerOnConnectFailed)
                that.delegate.CRBleManagerOnConnectFailed(device)
            clearTimeout(that.timeOut)
            that.timeOut = null
        }, 10000)
    }
    wx.createBLEConnection(
        {
            deviceId,
            success: (res) => {
                // this.setData({
                // 	connected: true,
                // 	name,
                // 	deviceId,
                // })
                this.getBLEDeviceServices(deviceId)
            }
        })
}

function writeBLECharacteristicValue() {
    // 向蓝牙设备发送一个0x00的16进制数据
    let buffer = new ArrayBuffer(0xaa, 0x55, 0x0f, 0x03, 0x85, 0x01, 0x24)
    let dataView = new DataView(buffer)
    dataView.setUint8(0, Math.random() * 255 | 0)
    wx.writeBLECharacteristicValue({
        deviceId: this._deviceId,
        serviceId: this._deviceId,
        characteristicId: this._characteristicId,
        value: buffer,
    })
}

function closeConnection(device) {
    if (device == null)
        return
    // const that = this
    wx.closeBLEConnection({
        deviceId: device.deviceID,
        success: (res) => {
            // if (that.delegate.CRBleManagerOnDidDisconnectDevice)
            // 	that.delegate.CRBleManagerOnDidDisconnectDevice(device)
            // that.deleteConnectedDeviceWithDeviceID(device.deviceID)
        }
    })
}

function closeBluetoothAdapter() {
    wx.closeBluetoothAdapter()
    this._discoveryStarted = false
}


function suportDevice(deviceName) {
    var sopportedDevice
    for (var i = 0; i < supportDevices.length; i++) {
        sopportedDevice = supportDevices[i]
        if (deviceName.indexOf(sopportedDevice) != -1)
            return true
    }
    return false
}


function isSpo2Device(name) {
    return ((name.indexOf(pod) != -1) || (name.indexOf(pc_60nw) != -1) || (name.indexOf(pc_60nw_1) != -1) || (name.indexOf(pc_66b) != -1) || (name.indexOf(pc_68b) != -1) || (name.indexOf(pc_60f) != -1) || (name.indexOf(oxySmart) != -1) || (name.indexOf(babyOximeter) != -1) || (name.indexOf(ap_10) != -1) || (name.indexOf(ap_20) != -1) || (name.indexOf(sp_20) != -1))

}

//接口方法
module.exports.setDelegate = setDelegate
module.exports.startSearch = startSearch
module.exports.connectDevice = connectDevice
module.exports.closeConnection = closeConnection
module.exports.suportDevice = suportDevice
module.exports.isSpo2Device = isSpo2Device


module.exports.stopSearch = stopSearch
module.exports.pc100 = pc100
module.exports.pc200 = pc200
module.exports.pc300 = pc300
module.exports.pc80b = pc80b
module.exports.h600 = h600
module.exports.pod = pod
module.exports.ap_10 = ap_10
module.exports.ap_20 = ap_20
module.exports.sp_20 = sp_20
module.exports.pc_60nw = pc_60nw
module.exports.pc_60nw_1 = pc_60nw_1
module.exports.pc_68b = pc_68b
module.exports.pc_66b = pc_66b

module.exports.pc_60f = pc_60f
module.exports.oxySmart = oxySmart
module.exports.babyOximeter = babyOximeter
